#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "minilzo.h"
#include "base64.h"
#include "utils2.h"


void StringEncode(char *buf, char *str, int size)
{
    base64_encode((const unsigned char*)str, size, (unsigned char*)buf);
}

int StringDecode(char *buf, char *str)
{
    return base64_decode((const unsigned char*)str, (unsigned char*)buf);
}

void xorEncode2(char *buf, int size)
{
	int i;
	for(i=0;i<size;i++)
	{
		buf[i]^=(char)(i%128);
	}
}

void xorEncode(char *buf, int size, char *key, int keySize)
{
	int i,j=0;
	if(key && keySize)
	for(i=0; i<size; i++)
	{
		buf[i]^=key[j++];
		if(j>=keySize) j=0;
	}
}

int bufferEncrypt(char *buf, int size, char *target, int targetSize, char *key, int keySize)
{
	char tmp[LZO1X_MEM_COMPRESS];
	int ret;
	lzo_uint retSize=targetSize;
	xorEncode(buf, size, key, keySize);
	ret=lzo1x_1_compress((const unsigned char*)buf, size, (unsigned char*)target, &retSize, tmp);
	if(ret==LZO_E_OK)
	{
		xorEncode2(target, retSize);
		return retSize;
	}
	return ret;
}

int bufferDecrypt(char *buf, int size, char *target, int targetSize, char *key, int keySize)
{
	int ret, retSize=targetSize;
	xorEncode2(buf, size);
	ret=lzo1x_decompress_safe((const unsigned char*)buf, size, (unsigned char*)target, (unsigned int*)&retSize, NULL);
	if(ret==LZO_E_OK)
	{
		xorEncode(target, retSize, key, keySize);
		return retSize;
	}
	return ret;
}

char *fileDecrypt(char *fname, int *size, char *key, int keySize)
{
	char *buffer, *fbuf;
	int flen, blen, ret;
	ssize_t retsize;
	FILE *f=fopen(fname,"rb");
	*size=blen=0;
	if(f==NULL) return NULL;
	fseek(f, 0, SEEK_END);
	flen=ftell(f);
	fseek(f, 0, SEEK_SET);
	if(flen>=8)
	{
		retsize = fread(&blen, 4, 1, f);
		if(memcmp(&blen,"LZO1",4)!=0)
		{
			fclose(f);
			return NULL;
		}
		retsize = fread(&blen, 4, 1, f);
	}
	flen-=8;
	if(flen<=0 || blen>flen*500 || blen>5*1024*1024)
	{
		fclose(f);
		return NULL;
	}
	buffer=(char*)malloc(blen);
	fbuf=(char*)malloc(flen);
	retsize = fread(fbuf, flen, 1, f);
	fclose(f);
	ret=bufferDecrypt(fbuf, flen, buffer, blen, key, keySize);
	free(fbuf);
	if(ret==blen)
	{
		*size=ret;
		return buffer;
	}
	free(buffer);
	return NULL;
}

char *loadFileMem(char *fname, int *fsize, int encrypt, char *key, int keySize)
{
	int flen;
	FILE *f;
	ssize_t retsize;
	char *buffer;
	if(encrypt==1)
		return fileDecrypt(fname, fsize, key, keySize);
	f=fopen(fname, "rb");
	if(f==NULL) return NULL;
	fseek(f, 0, SEEK_END);
	flen=ftell(f);
	*fsize=flen;
	fseek(f, 0, SEEK_SET);
	buffer=(char*)malloc(flen);
	if(buffer)
	{
		retsize = fread(buffer, flen, 1, f);
		fclose(f);
		return buffer;
	}
	return NULL;
}

